/*
 * Individual.h
 *
 *  Created on: Jan 9, 2012
 *      Author: luiz
 */

#ifndef INDIVIDUAL_H_
#define INDIVIDUAL_H_

#include <vector>

#include "Chromosome.h"
#include "Instance.h"
#include "Layer.h"
#include "GeneCell.h"

class Individual
{
    Chromosome *chromosome_;

    double fitness_;

    Layer *layer_;

    std::vector<int> convert_gene_cell_postition_to_int_vector(const std::vector<GeneCell> &vector_gene_cell) ;

    std::vector<int> convert_gene_cell_different_clock_zone_to_int_vector(const std::vector<GeneCell> &vector_gene_cell) ;

    std::vector<std::vector<Samples> > *traces_;

    double polarization_error_;

public:

    Individual(int chromossome_size=0);

    Individual(const Chromosome & chromosome, const Layer & layer,const std::vector<std::vector<Samples> > & traces = std::vector<std::vector<Samples> >());


    virtual ~Individual();

    Individual(const Individual &individual);

    Individual & operator=(const Individual &invidividual);

    void calculate_fitness(Instance &instance);

    double calculate_polarization_error(Instance &instance, std::vector<std::vector<Samples> > &results);

    Layer calculate_fitness_with_layer_default(Instance *instance,Layer *layer_default,Individual *better_individual=NULL);

    void recalculate_fitness(const double &alfa_value,Individual *better_individual=NULL);

    void generate_random_chromosome();

    std::vector<Individual> crossover(Individual & individual);

    Individual  mutation(double tax);

    Chromosome get_chromossome() const;

    void set_chromossome(const Chromosome & chromossome);

    bool operator()(const Individual & a, const Individual &b);

    bool operator< (const Individual &b)const;

    double fitness();

    void set_layer(const Layer &layer);

    Layer* layer();

    const Layer* layer() const;

    std::string print();

    void set_traces(const std::vector<std::vector<Samples> > & traces);

    std::vector<std::vector<Samples> > traces();

    double polarization_error() const;

    void set_polarization_error(const double & polarization_error);

    int layer_number_of_cells() const;

    bool is_valid(Instance & instance) const;

};

#endif /* INDIVIDUAL_H_ */
